use std::os::raw::{c_int, c_char};
use std::ptr;
use std::time::{Duration, Instant};
use std::collections::HashMap;
use std::sync::{Arc, Mutex};

use crate::RatatuiResult;

/// 性能指标类型
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RatatuiMetricType {
    RenderTime = 0,
    EventProcessTime = 1,
    MemoryUsage = 2,
    WidgetCount = 3,
    FrameRate = 4,
    LayoutTime = 5,
    DrawTime = 6,
}

/// 性能统计数据
#[repr(C)]
#[derive(Debug, Clone)]
pub struct RatatuiPerformanceStats {
    pub metric_type: RatatuiMetricType,
    pub current_value: f64,
    pub average_value: f64,
    pub min_value: f64,
    pub max_value: f64,
    pub sample_count: u64,
    pub total_time: f64,
}

/// 性能监控器
pub struct RatatuiPerformanceMonitor {
    pub enabled: bool,
    pub metrics: HashMap<RatatuiMetricType, Vec<f64>>,
    pub start_times: HashMap<RatatuiMetricType, Instant>,
    pub max_samples: usize,
}

impl RatatuiPerformanceMonitor {
    /// 创建新的性能监控器
    pub fn new() -> Self {
        RatatuiPerformanceMonitor {
            enabled: true,
            metrics: HashMap::new(),
            start_times: HashMap::new(),
            max_samples: 1000, // 最多保存1000个样本
        }
    }
    
    /// 开始计时
    pub fn start_timing(&mut self, metric_type: RatatuiMetricType) {
        if !self.enabled {
            return;
        }
        self.start_times.insert(metric_type, Instant::now());
    }
    
    /// 结束计时并记录
    pub fn end_timing(&mut self, metric_type: RatatuiMetricType) {
        if !self.enabled {
            return;
        }
        
        if let Some(start_time) = self.start_times.remove(&metric_type) {
            let duration = start_time.elapsed();
            let duration_ms = duration.as_secs_f64() * 1000.0;
            self.record_metric(metric_type, duration_ms);
        }
    }
    
    /// 记录指标值
    pub fn record_metric(&mut self, metric_type: RatatuiMetricType, value: f64) {
        if !self.enabled {
            return;
        }
        
        let samples = self.metrics.entry(metric_type).or_insert_with(Vec::new);
        samples.push(value);
        
        // 限制样本数量
        if samples.len() > self.max_samples {
            samples.remove(0);
        }
    }
    
    /// 获取性能统计
    pub fn get_stats(&self, metric_type: RatatuiMetricType) -> Option<RatatuiPerformanceStats> {
        if let Some(samples) = self.metrics.get(&metric_type) {
            if samples.is_empty() {
                return None;
            }
            
            let current_value = *samples.last().unwrap();
            let sum: f64 = samples.iter().sum();
            let average_value = sum / samples.len() as f64;
            let min_value = samples.iter().fold(f64::INFINITY, |a, &b| a.min(b));
            let max_value = samples.iter().fold(f64::NEG_INFINITY, |a, &b| a.max(b));
            
            Some(RatatuiPerformanceStats {
                metric_type,
                current_value,
                average_value,
                min_value,
                max_value,
                sample_count: samples.len() as u64,
                total_time: sum,
            })
        } else {
            None
        }
    }
    
    /// 重置所有指标
    pub fn reset(&mut self) {
        self.metrics.clear();
        self.start_times.clear();
    }
    
    /// 启用/禁用监控
    pub fn set_enabled(&mut self, enabled: bool) {
        self.enabled = enabled;
    }
}

/// 全局性能监控器
static GLOBAL_MONITOR: Mutex<Option<RatatuiPerformanceMonitor>> = Mutex::new(None);

/// 初始化性能监控
#[no_mangle]
pub extern "C" fn ratatui_performance_init() -> c_int {
    let mut monitor = GLOBAL_MONITOR.lock().unwrap();
    *monitor = Some(RatatuiPerformanceMonitor::new());
    RatatuiResult::Ok as c_int
}

/// 清理性能监控
#[no_mangle]
pub extern "C" fn ratatui_performance_cleanup() {
    let mut monitor = GLOBAL_MONITOR.lock().unwrap();
    *monitor = None;
}

/// 开始计时
#[no_mangle]
pub extern "C" fn ratatui_performance_start_timing(metric_type: RatatuiMetricType) -> c_int {
    let mut monitor = GLOBAL_MONITOR.lock().unwrap();
    if let Some(ref mut monitor) = *monitor {
        monitor.start_timing(metric_type);
        RatatuiResult::Ok as c_int
    } else {
        RatatuiResult::ErrorInvalidArgument as c_int
    }
}

/// 结束计时
#[no_mangle]
pub extern "C" fn ratatui_performance_end_timing(metric_type: RatatuiMetricType) -> c_int {
    let mut monitor = GLOBAL_MONITOR.lock().unwrap();
    if let Some(ref mut monitor) = *monitor {
        monitor.end_timing(metric_type);
        RatatuiResult::Ok as c_int
    } else {
        RatatuiResult::ErrorInvalidArgument as c_int
    }
}

/// 记录指标值
#[no_mangle]
pub extern "C" fn ratatui_performance_record_metric(
    metric_type: RatatuiMetricType,
    value: f64,
) -> c_int {
    let mut monitor = GLOBAL_MONITOR.lock().unwrap();
    if let Some(ref mut monitor) = *monitor {
        monitor.record_metric(metric_type, value);
        RatatuiResult::Ok as c_int
    } else {
        RatatuiResult::ErrorInvalidArgument as c_int
    }
}

/// 获取性能统计
#[no_mangle]
pub extern "C" fn ratatui_performance_get_stats(
    metric_type: RatatuiMetricType,
    stats: *mut RatatuiPerformanceStats,
) -> c_int {
    if stats.is_null() {
        return RatatuiResult::ErrorNullPointer as c_int;
    }
    
    let monitor = GLOBAL_MONITOR.lock().unwrap();
    if let Some(ref monitor) = *monitor {
        if let Some(performance_stats) = monitor.get_stats(metric_type) {
            unsafe {
                *stats = performance_stats;
            }
            RatatuiResult::Ok as c_int
        } else {
            RatatuiResult::ErrorInvalidArgument as c_int
        }
    } else {
        RatatuiResult::ErrorInvalidArgument as c_int
    }
}

/// 重置性能统计
#[no_mangle]
pub extern "C" fn ratatui_performance_reset() -> c_int {
    let mut monitor = GLOBAL_MONITOR.lock().unwrap();
    if let Some(ref mut monitor) = *monitor {
        monitor.reset();
        RatatuiResult::Ok as c_int
    } else {
        RatatuiResult::ErrorInvalidArgument as c_int
    }
}

/// 启用/禁用性能监控
#[no_mangle]
pub extern "C" fn ratatui_performance_set_enabled(enabled: bool) -> c_int {
    let mut monitor = GLOBAL_MONITOR.lock().unwrap();
    if let Some(ref mut monitor) = *monitor {
        monitor.set_enabled(enabled);
        RatatuiResult::Ok as c_int
    } else {
        RatatuiResult::ErrorInvalidArgument as c_int
    }
}

/// 获取内存使用情况
#[no_mangle]
pub extern "C" fn ratatui_performance_get_memory_usage() -> f64 {
    // 简化的内存使用情况获取
    // 在实际实现中，可以使用更精确的内存监控
    use std::alloc::{GlobalAlloc, Layout, System};
    
    // 这里返回一个模拟的内存使用值
    // 实际实现可能需要使用专门的内存监控库
    1024.0 * 1024.0 // 1MB 作为示例
}

/// 获取当前帧率
#[no_mangle]
pub extern "C" fn ratatui_performance_get_frame_rate() -> f64 {
    let monitor = GLOBAL_MONITOR.lock().unwrap();
    if let Some(ref monitor) = *monitor {
        if let Some(stats) = monitor.get_stats(RatatuiMetricType::FrameRate) {
            stats.current_value
        } else {
            0.0
        }
    } else {
        0.0
    }
}

/// 性能报告生成
#[no_mangle]
pub extern "C" fn ratatui_performance_generate_report() -> *mut c_char {
    let monitor = GLOBAL_MONITOR.lock().unwrap();
    if let Some(ref monitor) = *monitor {
        let mut report = String::new();
        report.push_str("=== Ratatui 性能报告 ===\n");
        
        let metrics = [
            RatatuiMetricType::RenderTime,
            RatatuiMetricType::EventProcessTime,
            RatatuiMetricType::MemoryUsage,
            RatatuiMetricType::WidgetCount,
            RatatuiMetricType::FrameRate,
            RatatuiMetricType::LayoutTime,
            RatatuiMetricType::DrawTime,
        ];
        
        for metric in &metrics {
            if let Some(stats) = monitor.get_stats(*metric) {
                report.push_str(&format!(
                    "{:?}: 当前={:.2}, 平均={:.2}, 最小={:.2}, 最大={:.2}, 样本数={}\n",
                    metric, stats.current_value, stats.average_value,
                    stats.min_value, stats.max_value, stats.sample_count
                ));
            }
        }
        
        match std::ffi::CString::new(report) {
            Ok(c_string) => c_string.into_raw(),
            Err(_) => ptr::null_mut(),
        }
    } else {
        ptr::null_mut()
    }
}
